1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.math;
18
19 import static java.math.BigInteger.ONE;
20 import static java.math.BigInteger.ZERO;
21 import static java.math.RoundingMode.CEILING;
22 import static java.math.RoundingMode.DOWN;
23 import static java.math.RoundingMode.FLOOR;
24 import static java.math.RoundingMode.HALF_DOWN;
25 import static java.math.RoundingMode.HALF_EVEN;
26 import static java.math.RoundingMode.HALF_UP;
27 import static java.math.RoundingMode.UP;
28 import static java.util.Arrays.asList;
29
30 import com.google.common.annotations.GwtCompatible;
31 import com.google.common.base.Function;
32 import com.google.common.base.Predicate;
33 import com.google.common.collect.ImmutableList;
34 import com.google.common.collect.ImmutableSet;
35 import com.google.common.collect.Iterables;
36 import com.google.common.primitives.Doubles;
37
38 import java.math.BigInteger;
39 import java.math.RoundingMode;
40
41
42
43
44
45
46 @GwtCompatible
47 public class MathTesting {
48 static final ImmutableSet<RoundingMode> ALL_ROUNDING_MODES = ImmutableSet.copyOf(RoundingMode
49 .values());
50
51 static final ImmutableList<RoundingMode> ALL_SAFE_ROUNDING_MODES = ImmutableList.of(DOWN, UP,
52 FLOOR, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN);
53
54
55 static final ImmutableList<Integer> EXPONENTS = ImmutableList.of(0, 1, 2, 3, 4, 7, 10, 15,
56 20, 25, 40, 70);
57
58
59 private static final Function<Integer, Long> TO_LONG = new Function<Integer, Long>() {
60 @Override
61 public Long apply(Integer n) {
62 return Long.valueOf(n);
63 }
64 };
65
66
67 private static final Function<Long, BigInteger> TO_BIGINTEGER =
68 new Function<Long, BigInteger>() {
69 @Override
70 public BigInteger apply(Long n) {
71 return BigInteger.valueOf(n);
72 }
73 };
74
75 private static final Function<Integer, Integer> NEGATE_INT = new Function<Integer, Integer>() {
76 @Override
77 public Integer apply(Integer x) {
78 return -x;
79 }
80 };
81
82 private static final Function<Long, Long> NEGATE_LONG = new Function<Long, Long>() {
83 @Override
84 public Long apply(Long x) {
85 return -x;
86 }
87 };
88
89 private static final Function<BigInteger, BigInteger> NEGATE_BIGINT =
90 new Function<BigInteger, BigInteger>() {
91 @Override
92 public BigInteger apply(BigInteger x) {
93 return x.negate();
94 }
95 };
96
97
98
99
100
101 static final ImmutableSet<Integer> POSITIVE_INTEGER_CANDIDATES;
102
103 static final Iterable<Integer> NEGATIVE_INTEGER_CANDIDATES;
104
105 static final Iterable<Integer> NONZERO_INTEGER_CANDIDATES;
106
107 static final Iterable<Integer> ALL_INTEGER_CANDIDATES;
108
109 static {
110 ImmutableSet.Builder<Integer> intValues = ImmutableSet.builder();
111
112 intValues.add(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
113
114 for (int i = 1; i <= 40; i++) {
115 intValues.add(i);
116 }
117
118 for (int exponent : asList(2, 3, 4, 9, 15, 16, 17, 24, 25, 30)) {
119 int x = 1 << exponent;
120 intValues.add(x, x + 1, x - 1);
121 }
122 intValues.add(9999).add(10000).add(10001).add(1000000);
123 intValues.add(5792).add(5793);
124 POSITIVE_INTEGER_CANDIDATES = intValues.build();
125 NEGATIVE_INTEGER_CANDIDATES = ImmutableList.copyOf(Iterables.concat(
126 Iterables.transform(POSITIVE_INTEGER_CANDIDATES, NEGATE_INT),
127 ImmutableList.of(Integer.MIN_VALUE)));
128 NONZERO_INTEGER_CANDIDATES = ImmutableList.copyOf(
129 Iterables.concat(POSITIVE_INTEGER_CANDIDATES, NEGATIVE_INTEGER_CANDIDATES));
130 ALL_INTEGER_CANDIDATES = Iterables.concat(NONZERO_INTEGER_CANDIDATES, ImmutableList.of(0));
131 }
132
133
134
135
136
137
138 static final ImmutableSet<Long> POSITIVE_LONG_CANDIDATES;
139
140 static final Iterable<Long> NEGATIVE_LONG_CANDIDATES;
141
142 static final Iterable<Long> NONZERO_LONG_CANDIDATES;
143
144 static final Iterable<Long> ALL_LONG_CANDIDATES;
145
146 static {
147 ImmutableSet.Builder<Long> longValues = ImmutableSet.builder();
148
149 longValues.addAll(Iterables.transform(POSITIVE_INTEGER_CANDIDATES, TO_LONG));
150
151 longValues.add(Integer.MAX_VALUE + 1L, Long.MAX_VALUE - 1L, Long.MAX_VALUE);
152
153
154 for (int exponent : asList(32, 33, 39, 40, 41, 47, 48, 49, 55, 56, 57)) {
155 long x = 1L << exponent;
156 longValues.add(x, x + 1, x - 1);
157 }
158 longValues.add(194368031998L).add(194368031999L);
159 POSITIVE_LONG_CANDIDATES = longValues.build();
160 NEGATIVE_LONG_CANDIDATES =
161 Iterables.concat(Iterables.transform(POSITIVE_LONG_CANDIDATES, NEGATE_LONG),
162 ImmutableList.of(Long.MIN_VALUE));
163 NONZERO_LONG_CANDIDATES = Iterables.concat(POSITIVE_LONG_CANDIDATES, NEGATIVE_LONG_CANDIDATES);
164 ALL_LONG_CANDIDATES = Iterables.concat(NONZERO_LONG_CANDIDATES, ImmutableList.of(0L));
165 }
166
167
168
169
170
171
172 static final ImmutableSet<BigInteger> POSITIVE_BIGINTEGER_CANDIDATES;
173
174 static final Iterable<BigInteger> NEGATIVE_BIGINTEGER_CANDIDATES;
175
176 static final Iterable<BigInteger> NONZERO_BIGINTEGER_CANDIDATES;
177
178 static final Iterable<BigInteger> ALL_BIGINTEGER_CANDIDATES;
179
180 static {
181 ImmutableSet.Builder<BigInteger> bigValues = ImmutableSet.builder();
182
183 bigValues.addAll(Iterables.transform(POSITIVE_LONG_CANDIDATES, TO_BIGINTEGER));
184
185 bigValues.add(BigInteger.valueOf(Long.MAX_VALUE).add(ONE));
186
187 for (int exponent : asList(64, 65, 71, 72, 73, 79, 80, 81, 255, 256, 257, 511, 512, 513,
188 Double.MAX_EXPONENT - 1, Double.MAX_EXPONENT, Double.MAX_EXPONENT + 1)) {
189 BigInteger x = ONE.shiftLeft(exponent);
190 bigValues.add(x, x.add(ONE), x.subtract(ONE));
191 }
192 bigValues.add(new BigInteger("218838949120258359057546633"));
193
194 bigValues.add(new BigInteger("218838949120258359057546634"));
195 POSITIVE_BIGINTEGER_CANDIDATES = bigValues.build();
196 NEGATIVE_BIGINTEGER_CANDIDATES =
197 Iterables.transform(POSITIVE_BIGINTEGER_CANDIDATES, NEGATE_BIGINT);
198 NONZERO_BIGINTEGER_CANDIDATES =
199 Iterables.concat(POSITIVE_BIGINTEGER_CANDIDATES, NEGATIVE_BIGINTEGER_CANDIDATES);
200 ALL_BIGINTEGER_CANDIDATES =
201 Iterables.concat(NONZERO_BIGINTEGER_CANDIDATES, ImmutableList.of(ZERO));
202 }
203
204 static final ImmutableSet<Double> INTEGRAL_DOUBLE_CANDIDATES;
205 static final ImmutableSet<Double> FRACTIONAL_DOUBLE_CANDIDATES;
206 static final Iterable<Double> INFINITIES = Doubles.asList(
207 Double.POSITIVE_INFINITY,
208 Double.NEGATIVE_INFINITY);
209 static final Iterable<Double> FINITE_DOUBLE_CANDIDATES;
210 static final Iterable<Double> POSITIVE_FINITE_DOUBLE_CANDIDATES;
211 static final Iterable<Double> ALL_DOUBLE_CANDIDATES;
212 static final Iterable<Double> DOUBLE_CANDIDATES_EXCEPT_NAN;
213 static {
214 ImmutableSet.Builder<Double> integralBuilder = ImmutableSet.builder();
215 ImmutableSet.Builder<Double> fractionalBuilder = ImmutableSet.builder();
216 integralBuilder.addAll(Doubles.asList(0.0, -0.0, Double.MAX_VALUE, -Double.MAX_VALUE));
217
218 for (int scale = 1; scale <= 4; scale++) {
219 for (double d : Doubles.asList(Double.MIN_VALUE, Double.MIN_NORMAL)) {
220 fractionalBuilder.add(d * scale).add(-d * scale);
221 }
222 }
223 for (double d : Doubles.asList(0, 1, 2, 7, 51, 102, Math.scalb(1.0, 53), Integer.MIN_VALUE,
224 Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE)) {
225 for (double delta : Doubles.asList(0.0, 1.0, 2.0)) {
226 integralBuilder.addAll(Doubles.asList(d + delta, d - delta, -d - delta, -d + delta));
227 }
228 for (double delta : Doubles.asList(0.01, 0.1, 0.25, 0.499, 0.5, 0.501, 0.7, 0.8)) {
229 double x = d + delta;
230 if (x != Math.round(x)) {
231 fractionalBuilder.add(x);
232 }
233 }
234 }
235 INTEGRAL_DOUBLE_CANDIDATES = integralBuilder.build();
236 fractionalBuilder.add(1.414).add(1.415).add(Math.sqrt(2));
237 fractionalBuilder.add(5.656).add(5.657).add(4 * Math.sqrt(2));
238 for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
239 double x = 1 / d;
240 if (x != Math.rint(x)) {
241 fractionalBuilder.add(x);
242 }
243 }
244 FRACTIONAL_DOUBLE_CANDIDATES = fractionalBuilder.build();
245 FINITE_DOUBLE_CANDIDATES =
246 Iterables.concat(FRACTIONAL_DOUBLE_CANDIDATES, INTEGRAL_DOUBLE_CANDIDATES);
247 POSITIVE_FINITE_DOUBLE_CANDIDATES =
248 Iterables.filter(FINITE_DOUBLE_CANDIDATES, new Predicate<Double>() {
249 @Override
250 public boolean apply(Double input) {
251 return input.doubleValue() > 0.0;
252 }
253 });
254 DOUBLE_CANDIDATES_EXCEPT_NAN = Iterables.concat(FINITE_DOUBLE_CANDIDATES, INFINITIES);
255 ALL_DOUBLE_CANDIDATES =
256 Iterables.concat(DOUBLE_CANDIDATES_EXCEPT_NAN, asList(Double.NaN));
257 }
258 }